package com.ali.config;

import com.auth0.jwt.interfaces.Claim;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

/**
 * JWT过滤器
 */
@Slf4j
public class JWTFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //模拟获取token
        String token = request.getQueryString();

        if (StringUtils.hasLength(token)) {
            Map<String, Claim> claimsMap = null;
            try {
                claimsMap = JWTUtil.tokenVerify(token);
            } catch (Exception e) {
                log.info("获取token异常");
            }

            System.out.println("claimsMap：" + claimsMap);
            if (claimsMap == null) {
                throw new RuntimeException("token异常");
            }

            String username = String.valueOf(claimsMap.get("username"));

            //JWT验证通过时，直接生成认证信息
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());

            WebAuthenticationDetailsSource webAuthenticationDetailsSource = new WebAuthenticationDetailsSource();
            webAuthenticationDetailsSource.buildDetails(request);
            usernamePasswordAuthenticationToken.setDetails(webAuthenticationDetailsSource);

            SecurityContext securityContext = SecurityContextHolder.getContext();
            securityContext.setAuthentication(usernamePasswordAuthenticationToken);
        }

        filterChain.doFilter(request, response);
    }
}
